package com.hsogoo.collate.utils;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.InputStream;
import java.util.*;

@Slf4j
public class SftpUtils {

    private static SftpUtils sftpUtil;
    private static ChannelSftp sftp;
    private String host;
    private int port;
    private String userName;
    private String password;

    private SftpUtils(String host, int port, String userName, String password) {
        this.host = host;
        this.port = port;
        this.userName = userName;
        this.password = password;
    }

    /**
     * 获得Smb连接对象
     * @param host
     * @param port
     * @param userName
     * @param password
     * @return
     */
    public static synchronized SftpUtils getInstance(String host, int port,
                                                    String userName, String password) {
        if (sftpUtil == null) {
            sftpUtil = new SftpUtils(host, port, userName, password);
        }
        return sftpUtil;
    }

    /**
     * 连接初始化
     * @return
     */
    public ChannelSftp getSftp() {
        JSch jsch = new JSch();
        Channel channel = null;
        try {
            Session sshSession = jsch.getSession(this.userName, this.host, this.port);
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect(20000);
            channel = sshSession.openChannel("sftp");
            channel.connect();
        } catch (JSchException e) {
            log.info("getSftp exception：", e);
        }
        return (ChannelSftp) channel;
    }

    public void disconnect() throws Exception {
        if (sftp != null) {
            if (sftp.isConnected()) {
                sftp.disconnect();
            } else if (sftp.isClosed()) {
                log.info("Session close...........");
            }
        }
    }

    /**
     * 读取目录下文件流
     *
     * @param directory
     * @throws Exception
     *             void
     * @author wangqinghua
     * @date 2015-9-24 下午1:58:17
     */
    public Map<String,InputStream> readStreamByDirectory(ChannelSftp c, String directory){
        log.info("远程文件地址：{}",directory);
        Map<String,InputStream> inputStreams = new HashMap<>();
        if (StringUtils.isBlank(directory)) {
            log.error("远程文件地址不能为空");
            return null;
        }
        try {

            String downloadFile = "";
            List<String> downloadFileList = this.listFiles(c,directory);
            Iterator<String> it = downloadFileList.iterator();
            InputStream streatm = null;
            String fileName = null;
            String[] fileNames = null;
            while (it.hasNext()) {
                downloadFile = it.next().toString();
                if (downloadFile.toString().indexOf(".") < 0) {
                    continue;
                }
                fileNames = downloadFile.split("/");
                fileName = fileNames[fileNames.length-1];
                log.info("循环文件列表：{}",fileName);
                streatm = c.get(downloadFile);
                inputStreams.put(fileName,streatm);
            }

        } catch (Exception e) {
            log.error("SFTP文件流读取失败，失败信息：", e);
            return null;
        } finally {
            try {
                this.disconnect();
            } catch (Exception e) {
                log.error("sftp异常,{}",e);
            }
        }
        log.info("SFTP文件流读取完成");
        return inputStreams;
    }


    /**
     * 获得目录下的所有文件名
     *
     * @Title: listFiles
     * @param directory
     * @return
     * @throws Exception
     *             List<String>
     * @author wangqinghua
     * @date 2015-9-24 下午1:53:40
     */
    @SuppressWarnings("rawtypes")
    public List<String> listFiles(ChannelSftp sftp,String directory) throws Exception {
        Vector fileList;
        List<String> fileNameList = new ArrayList<String>();
        fileList = sftp.ls(directory);
        Iterator it = fileList.iterator();
        while (it.hasNext()) {
            String fileName = ((ChannelSftp.LsEntry) it.next()).getFilename();
            if (".".equals(fileName) || "..".equals(fileName)) {
                continue;
            }
            fileNameList.add(directory+"/"+fileName);
        }
        return fileNameList;
    }

}
